var stockChannelDAO = require('../controller/controller.stockChannel');
var stockPositionDAO = require('../controller/controller.stockPosition');
var stockGroupDAO = require('../controller/controller.stockGroup');
var stockDealDAO = require('../controller/controller.stockDeal');
var stockHistoryPriceDAO = require('../controller/controller.stockHistoryPrice');

var stockUtil = require('../utils/stock');
var timeUtil = require('../utils/timeUtil');
var async = require('async');
module.exports = {
    getGroupRealVal: function (stockGroupId, callback) {
        if (!stockGroupId) {
            callback({code: 400, message: 'invalid stockGroupId.'});
            return;
        }
        async.waterfall([//按股票查询实价
            function (cb) {
                stockPositionDAO.findByGroupId({stockGroupId: stockGroupId}, function (err, res) {
                    if(err){
                        cb(err);
                    }else{
                        cb(null, res.obj);
                    }
                });
            },
            function (stockPosition,cb) {
                stockGroupDAO.get({rowId: stockGroupId}, function (err, result) {
                    if(err){
                        cb(err);
                    }else{
                        stockPosition.stockGroupId = result.obj;
                        cb(null, stockPosition);
                    }
                });
            },
            function (stockPosition,cb) {
                stockChannelDAO.getByGroupId({stockGroupId: stockGroupId}, function (err, res) {
                    stockPosition.stockGroupId.stockChannelIds = res.obj;
                    var stockCodes = [];
                    for (stockChannel of res.obj) {
                        stockCodes.push(stockChannel.stockId.stockCode);
                    }
                    stockPosition.stockCodes = stockCodes;
                    cb(err, stockPosition);
                });
            },
            function (stockPosition, cb) {
                var stockCodes = stockPosition.stockCodes;
                var price = stockPosition.balance;
                //组合实际市值
                stockPosition.stockGroupId.realVal = 0;
                if (stockCodes.length == 0) {
                    stockPosition.stockGroupId.allVal = stockPosition.stockGroupId.realVal + price;
                    stockPosition.stockGroupId.realRate = (stockPosition.stockGroupId.realVal/stockPosition.stockGroupId.allVal*100).toFixed(2);
                    cb(null, stockPosition.stockGroupId);
                } else {
                    stockUtil.getRealtimeListPrice(stockCodes, function (err, res) {
                        var i = 0;

                        for (stockChannel of stockPosition.stockGroupId.stockChannelIds) {
                            stockChannel.stockId.realPrice = res[i];
                            stockChannel.stockId.realVal =  res[i] * stockChannel.positionNum;//单股实际市值
                            stockPosition.stockGroupId.realVal += res[i] * stockChannel.positionNum;//组合实际市值
                            i++;
                        }
                        stockPosition.stockGroupId.allVal = stockPosition.stockGroupId.realVal + price;//持股总市值（包含成本）
                        stockPosition.stockGroupId.realRate = (stockPosition.stockGroupId.realVal/stockPosition.stockGroupId.allVal*100).toFixed(2);

                        cb(err, stockPosition.stockGroupId);
                    });
                }
            }
        ], function (err, res) {
            callback(err, res);
        });

    },
    formatDate:function(date,type,num) {
        if(num){
            if(type == 'year'){
                date.setYear( date.getFullYear()+num );
            }
            if(type == 'month' ){
                date.setMonth( date.getMonth()+num );
            }
            if(type == 'day' ){
                date.setDate( date.getDate()+num );
            }
        }
        return timeUtil.timeFormate(date);
    },
    getAfterFiveDay:function(day, dayLen) {
        var days = [];
        var d = new Date(day.replace(/-/g, "/"));
        var i = dayLen < 5 ?1:dayLen / 5 ;//当前日期加i天,小于5天算一天
        var count = i==1?dayLen:5;
        for (var j = 0; j < count; j++) {
            d.setDate(d.getDate() + i);
            days.push(this.formatDate(d));
        }
        return (days);
    },
    getTime2Time:function ($time1, $time2) {
        var time1 = arguments[0], time2 = arguments[1];
        time1 = Date.parse(time1) / 1000;
        time2 = Date.parse(time2) / 1000;
        var time_ = time1 - time2;
        return parseInt(time_ / (3600 * 24));
    },
    countGroupRate: function (stockGroup, callback) {
        var that = this;

        //async.each(stockGroup.stockChannelIds, function (stockChannel, ca) {
            var minDate = new Date();
            async.waterfall([
                function (cb) {//查询当前组合最小交易时间
                    stockGroupDAO.findMinDealDate({stockGroupId:stockGroup.rowId},function (err,res) {
                            if(err || !res.obj[0].dealDate){
                                callback(err)
                                return;
                            }
                            minDate = res.obj&&res.obj[0].dealDate||new Date();
                            var threeMonth = new Date(that.formatDate(new Date(),'month',-2));
                            if(threeMonth.getTime()>minDate.getTime())//判断三个月是否小于最小交易日期
                                minDate = threeMonth;
                            stockGroup.minDate = minDate;
                            cb(null,stockGroup);
                    })
                },
                function (stockGroup,cb) {
                    var now = that.formatDate(new Date());
                    var dayLen = that.getTime2Time(now, that.formatDate(minDate));
                    var fiveDays = that.getAfterFiveDay(that.formatDate(minDate), dayLen);
                    var channelRates = [];
                    async.each(fiveDays, function (day, ca) {
                        var nextDay = that.formatDate(new Date(day),'day',1);
                        var paramDay = that.formatDate(new Date(day),'day',2);
                        var stockCodes = [];
                        var channelNums = [];
                                async.waterfall([
                                    function(call){
                                        stockGroupDAO.findChannelNumByDate({date:day,stockGroupId:stockGroup.rowId},function (err,res) {
                                            if (err) {
                                                console.log(err)
                                            } else {
                                                channelNums = res.obj;
                                                for (channelNum of channelNums) {
                                                    channelNum.stockCode = channelNum.stockCode.substring(0, channelNum.stockCode.indexOf("."));
                                                    stockCodes.push(channelNum.stockCode);
                                                }

                                                call(null,stockCodes);
                                            }
                                        });
                                    },
                                    function (stockCodes,call) {
                                        if(stockCodes && stockCodes.length ==0){
                                            call(null,[]);
                                            return;
                                        }
                                        stockHistoryPriceDAO.getListPriceByTime({
                                            date: nextDay,
                                            stockCodes: stockCodes
                                        }, function (err, result) {
                                            if (err) {
                                                console.log(err)
                                            } else {
                                                var i = 0;
                                                for (deal of result.obj) {
                                                    channelNums[i].realVal = deal.price * channelNums[i].nums;
                                                    channelNums[i].day = day;
                                                    i++;
                                                }
                                                call(null,channelNums);
                                            }
                                        });
                                    },function (channelNums,call) {

                                        stockHistoryPriceDAO.getListPriceByTime({
                                            date: paramDay,
                                            stockCodes: stockCodes
                                        }, function (err, result) {
                                            if (err) {
                                                call(err)
                                            } else {
                                                var i = 0;
                                                var newRate = {};
                                                var thisRateDay  = "";
                                                var thisAllPrice = 0;
                                                var nextAllPrice = 0;
                                                for (deal of result.obj) {
                                                    thisRateDay = channelNums[i].day;
                                                    thisAllPrice += parseInt(channelNums[i].realVal);
                                                    nextAllPrice += parseInt(deal.price *channelNums[i].nums);
                                                    // allNum += channelNums[i].nums;
                                                    // console.log((deal.price *channelNums[i].nums - channelNums[i].realVal)/channelNums[i].realVal*100)
                                                    // channelNums[i].realRate = ((deal.price *channelNums[i].nums - channelNums[i].realVal)/channelNums[i].realVal*100).toFixed(2);
                                                    // channelRates.push(channelNums[i]);
                                                    // newRate.date = thisRateDay;
                                                    i++;
                                                }
                                                newRate.realRate = ((nextAllPrice - thisAllPrice)/thisAllPrice*100).toFixed(2);
                                                newRate.day = thisRateDay;
                                                channelRates.push(newRate);
                                                call(null,channelRates)
                                            }
                                        })
                                    },
                                    ],function (err,result) {
                                        ca(err,channelRates)
                                });

                    },function (err) {
                        cb(err,channelRates)
                    })

                },
            ], function (err, res) {
                console.log(res);
                callback(err,res);
            })


        //})
    },
    getRealRate: function (importPrice, stockCode, callback) {
        let that = this;
        that.getRealtimePrice(stockCode, function (err, realtimePrice) {
            callback(err, !err && that.calcRate(importPrice, realtimePrice));
        });
    },

    /**
     * 计算盈利率
     * @param numerator 实际值
     * @param denominator 参考值
     * @returns {*}
     */
    calcRate: function (numerator, denominator) {
        let n = parseFloat(numerator);
        let m = parseFloat(denominator);
        if (isNaN(n) || isNaN(m) || m == 0) {
            return null;
        }
        let rate = (numerator - denominator) * 100 / denominator;
        return rate.toFixed(2) + '%';
    }

};